﻿using IDBContext;
using IEntities;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Repository
{
    public class SugarRepository<TEntity> : BaseRepository<TEntity> where TEntity : class, IEntity, new()
    {
        private IBaseContext<TEntity> _context;
        private SimpleClient<TEntity> entityDB;

        public SugarRepository(IBaseContext<TEntity> context)
        {
            _context = context;
            entityDB = _context.EntityContext as SimpleClient<TEntity>;
        }

        public override object[] Test() => new TEntity().GetKeys();

        public override int Count()
        {
            return entityDB.GetList().Count;
        }

        public override int Count(Expression<Func<TEntity, bool>> whereExpression)
        {
            return entityDB.Count(whereExpression);
        }

        public override Task<int> CountAsync()
        {
            return Task.FromResult(entityDB.GetListAsync().Result.Count);
        }

        public override Task<int> CountAsync(Expression<Func<TEntity, bool>> whereExpression)
        {
            return entityDB.CountAsync(whereExpression);
        }

        public override bool Delete(TEntity entity)
        {
            return entityDB.Delete(entity);
        }

        public override bool Deletes(dynamic[] ids)
        {
            return entityDB.DeleteByIds(ids);
        }

        public override Task DeletesAsync(dynamic[] ids)
        {
            return entityDB.DeleteByIdsAsync(ids);
        }

        public override Task DeleteAsync(TEntity entity)
        {
            return entityDB.DeleteAsync(entity);
        }

        public override bool DeleteByID(object id)
        {
            return entityDB.DeleteById(id);
        }

        public override Task DeleteByIDAsync(object id)
        {
            return entityDB.DeleteByIdAsync(id);
        }

        public override TEntity Find(Expression<Func<TEntity, bool>> whereExpression)
        {
            return entityDB.GetSingle(whereExpression);
        }

        public override Task<TEntity> FindAsync(Expression<Func<TEntity, bool>> whereExpression)
        {
            return entityDB.GetSingleAsync(whereExpression);
        }

        public override TEntity FindByID(object id)
        {
            return entityDB.GetById(id);
        }

        public override Task<TEntity> FindByIDAsync(object id)
        {
            return entityDB.GetByIdAsync(id);
        }

        public override TEntity FirstOrDefault(object id)
        {
            return FindByID(id);
        }

        public override TEntity FirstOrDefault(Expression<Func<TEntity, bool>> whereExpression)
        {
            return Find(whereExpression);
        }

        public override Task<TEntity> FirstOrDefaultAsync(object id)
        {
            return null;
        }

        public override Task<TEntity> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> whereExpression)
        {
            return FindAsync(whereExpression);
        }

        public override TEntity Get(object id)
        {
            return FindByID(id);
        }

        public override TEntity Get(Expression<Func<TEntity, bool>> whereExpression)
        {
            return Find(whereExpression);
        }

        public override List<TEntity> GetAllList()
        {
            return entityDB.GetList();
        }

        public override List<TEntity> GetAllList(Expression<Func<TEntity, bool>> whereExpression)
        {
            return entityDB.GetList(whereExpression);
        }

        public override Task<List<TEntity>> GetAllListAsync()
        {
            return entityDB.GetListAsync();
        }

        public override Task<List<TEntity>> GetAllListAsync(Expression<Func<TEntity, bool>> whereExpression)
        {
            return entityDB.GetListAsync(whereExpression);
        }

        public override Task<TEntity> GetAsync(object id)
        {
            return FindByIDAsync(id);
        }

        public override Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> whereExpression)
        {
            return FindAsync(whereExpression);
        }

        public override TEntity Insert(TEntity entity)
        {
            return entityDB.Insert(entity) == true ? entity : null;
        }

        public override object InsertAndGetID(TEntity entity)
        {
            if (entityDB.IsAny(x => x.GetKeys() == entity.GetKeys()))
            {
                return UpdateAndGetID(entity);
            }
            else
            {
                return entityDB.Insert(entity) == true ? entity.GetKeys().GetValue(0) : null;
            }
        }

        public override Task<object> InsertAndGetIDAsync(TEntity entity)
        {
            if (entityDB.IsAnyAsync(x => x.GetKeys() == entity.GetKeys()).Result)
            {
                return UpdateAndGetIDAsync(entity);
            }
            else
            {
                return entityDB.InsertAsync(entity).Result == true ? Task.FromResult(entity.GetKeys().GetValue(0)) : null;
            }
        }

        public override Task<TEntity> InsertAsync(TEntity entity)
        {
            return entityDB.InsertAsync(entity).Result == true ? Task.FromResult(entity) : null;
        }

        public override List<TEntity> Query(Expression<Func<TEntity, bool>> whereExpression)
        {
            return GetAllList(whereExpression);
        }

        public override Task<List<TEntity>> QueryAsync(Expression<Func<TEntity, bool>> whereExpression)
        {
            return GetAllListAsync(whereExpression);
        }

        public override List<TEntity> QueryPage(Expression<Func<TEntity, bool>> whereExpression, int pageIndex = 1, int pageSize = 10, int pageCount = 10)
        {
            return entityDB.GetPageList(whereExpression, new PageModel { PageIndex = pageIndex, PageSize = pageSize, PageCount = pageCount });
        }

        public override Task<List<TEntity>> QueryPageAsync(Expression<Func<TEntity, bool>> whereExpression, int pageIndex = 1, int pageSize = 10, int pageCount = 10)
        {
            return entityDB.GetPageListAsync(whereExpression, new PageModel { PageIndex = pageIndex, PageSize = pageSize, PageCount = pageCount });
        }

        public override TEntity Update(TEntity entity)
        {
            return entityDB.Update(entity) == true ? entity : null;
        }

        public override object UpdateAndGetID(TEntity entity)
        {
            return entityDB.Update(entity) == true ? entity.GetKeys().GetValue(0) : null;
        }

        public override Task<object> UpdateAndGetIDAsync(TEntity entity)
        {
            return entityDB.UpdateAsync(entity).Result == true ? Task.FromResult(entity.GetKeys().GetValue(0)) : null;
        }

        public override Task<TEntity> UpdateAsync(TEntity entity)
        {
            return entityDB.UpdateAsync(entity).Result == true ? Task.FromResult(entity) : null;
        }

        public override List<TEntity> Updates(List<TEntity> entities)
        {
            return entityDB.UpdateRange(entities) == true ? entities : null;
        }

        public override Task<List<TEntity>> UpdatesAsync(List<TEntity> entities)
        {
            return entityDB.UpdateRangeAsync(entities).Result == true ? Task.FromResult(entities) : null;
        }
    }
}
